package com.semanticweb.webapp.model.ontology;

import org.apache.lucene.document.Document;

import com.semanticweb.webapp.ontology.CIDOC;
import com.semanticweb.webapp.ontology.CType;
import com.semanticweb.webapp.ontology.Ont;
import com.semanticweb.webapp.ontology.Query;
import com.semanticweb.webapp.search.IDocument;
import com.semanticweb.webapp.search.SearchMD;
import com.semanticweb.webapp.util.StringUtil;

public class Museum extends AbstractEntity implements IDocument {

    private String country;
    private String city;
    private String museum;

    public static final String ONT_PLACE = "place";
    public static final String ONT_NAME = "name";
    public static final String ONT_COUNTRY = "country";
    public static final String ONT_CITY = "city";
    public static final String ONT_MUSEUM = "museum";

    public Museum(final String id) {
        super(id);
    }

    public Museum(final String id, final String country, final String city, final String museum) {
        super(id);
        this.country = country;
        this.city = city;
        this.museum = museum;
    }

    public String getCountry() {
        return this.country;
    }

    public void setCountry(final String country) {
        this.country = country;
    }

    public String getCity() {
        return this.city;
    }

    public void setCity(final String city) {
        this.city = city;
    }

    public String getMuseum() {
        return this.museum;
    }

    public void setMuseum(final String museum) {
        this.museum = museum;
    }

    @Override
    public void toRDF() {
        Ont.typeCheck(CType.COUNTRY);
        Ont.typeCheck(CType.CITY);
        Ont.typeCheck(CType.MUSEUM);

        final String countryURI = createCountry(this.country);
        final String cityURI = createCity(this.city, countryURI);
        final String museumURI = createMuseum(this.museum, cityURI);

        // connect
        if (museumURI != null) {
            Ont.getOntology().connectIndividuals(Item.formatItemURI(this.id), CIDOC.P55.getFullValue(), museumURI);
        }
    }

    public void fromRDF() {
        final String itemQueryValue = Item.formatItemQueryURI(this.id);
        final Query q = new Query();
        String[] result;

        // museum
        result = q.select("museum").connect(itemQueryValue, CIDOC.P55.queryValue(), "museum")
                .connect("museum", CIDOC.P2.queryValue(), CType.MUSEUM.queryValue()).find();
        if (result == null || result.length == 0) {
            return;
        }
        final String museumURI = Ont.formatQueryURI(Ont.isolateURISuffix(result[0]));

        result = q.selectLabel().connect(museumURI, CIDOC.P87.queryValue(), "museum").findLabel("museum");
        if (result == null || result.length == 0) {
            return;
        }
        this.museum = result[0];

        // city
        result = q.select("city").connect(museumURI, CIDOC.P89.queryValue(), "city")
                .connect("city", CIDOC.P2.queryValue(), CType.CITY.queryValue()).find();
        if (result == null || result.length == 0) {
            return;
        }
        final String cityURI = Ont.formatQueryURI(Ont.isolateURISuffix(result[0]));

        result = q.selectLabel().connect(cityURI, CIDOC.P87.queryValue(), "city").findLabel("city");
        if (result == null || result.length == 0) {
            return;
        }
        this.city = result[0];

        // country
        result = q.select("country").connect(cityURI, CIDOC.P89.queryValue(), "country")
                .connect("country", CIDOC.P2.queryValue(), CType.COUNTRY.queryValue()).find();
        if (result == null || result.length == 0) {
            return;
        }
        final String countryURI = Ont.formatQueryURI(Ont.isolateURISuffix(result[0]));

        result = q.selectLabel().connect(countryURI, CIDOC.P87.queryValue(), "country").findLabel("country");
        if (result == null || result.length == 0) {
            return;
        }
        this.country = result[0];

    }

    private String placeURI(final String id, final String value) {
        return Ont.formatURI(id, ONT_PLACE, value);
    }

    private String placeNameURI(final String id, final String value) {
        return Ont.formatURI(id, ONT_PLACE, ONT_NAME, value);
    }

    private String createCountry(final String countryName) {
        if (StringUtil.isNullOrEmpty(countryName)) {
            return null;
        }

        final Query query = new Query();
        final String[] find = query.select("country").type("e44", CIDOC.E44.queryValue()).label("e44", countryName)
                .type("country", CIDOC.E53.queryValue()).connect("country", CIDOC.P87.queryValue(), "e44")
                .connect("country", CIDOC.P2.queryValue(), CType.COUNTRY.queryValue()).find();
        if (find != null && find.length > 0) {
            return find[0];
        } else {
            final String placeURI = placeURI(this.id, ONT_COUNTRY);
            final String placeNameURI = placeNameURI(this.id, ONT_COUNTRY);

            Ont.getOntology().createIndividual(CIDOC.E53.getFullValue(), placeURI);
            Ont.getOntology().createIndividual(CIDOC.E44.getFullValue(), placeNameURI);

            Ont.getOntology().addLabel(placeNameURI, countryName);

            Ont.getOntology().connectIndividuals(placeURI, CIDOC.P2.getFullValue(), CType.COUNTRY.getURI());
            Ont.getOntology().connectIndividuals(placeURI, CIDOC.P87.getFullValue(), placeNameURI);

            return placeURI;
        }
    }

    private String createCity(final String cityName, final String countryURI) {
        if (StringUtil.isNullOrEmpty(cityName)) {
            return null;
        }

        String[] find = null;
        if (!StringUtil.isNullOrEmpty(countryURI)) {
            final String countryURISufix = Ont.isolateURISuffix(countryURI);
            final String countryQueryValue = Ont.formatQueryURI(countryURISufix);

            final Query q = new Query();
            find = q.select("city").type("e44", CIDOC.E44.queryValue()).label("e44", cityName)
                    .type("city", CIDOC.E53.queryValue()).connect("city", CIDOC.P87.queryValue(), "e44")
                    .connect("city", CIDOC.P2.queryValue(), CType.CITY.queryValue())
                    .connect("city", CIDOC.P89.queryValue(), countryQueryValue).find();
        }

        if (find != null && find.length > 0) {
            return find[0];
        } else {
            final String placeURI = placeURI(this.id, ONT_CITY);
            final String placeNameURI = placeNameURI(this.id, ONT_CITY);

            Ont.getOntology().createIndividual(CIDOC.E53.getFullValue(), placeURI);
            Ont.getOntology().createIndividual(CIDOC.E44.getFullValue(), placeNameURI);

            Ont.getOntology().addLabel(placeNameURI, cityName);

            Ont.getOntology().connectIndividuals(placeURI, CIDOC.P2.getFullValue(), CType.CITY.getURI());
            Ont.getOntology().connectIndividuals(placeURI, CIDOC.P87.getFullValue(), placeNameURI);

            if (!StringUtil.isNullOrEmpty(countryURI)) {
                Ont.getOntology().connectIndividuals(placeURI, CIDOC.P89.getFullValue(), countryURI);
            }

            return placeURI;
        }
    }

    private String createMuseum(final String museum, final String cityURI) {
        if (StringUtil.isNullOrEmpty(museum)) {
            return null;
        }

        String[] find = null;
        if (!StringUtil.isNullOrEmpty(cityURI)) {
            final String cityURISufix = Ont.isolateURISuffix(cityURI);
            final String cityQueryValue = Ont.formatQueryURI(cityURISufix);

            final Query query = new Query();
            find = query.select("museum").type("e44", CIDOC.E44.queryValue()).label("e44", museum)
                    .type("museum", CIDOC.E53.queryValue()).connect("museum", CIDOC.P87.queryValue(), "e44")
                    .connect("museum", CIDOC.P2.queryValue(), CType.MUSEUM.queryValue())
                    .connect("museum", CIDOC.P89.queryValue(), cityQueryValue).find();
        }

        if (find != null && find.length > 0) {
            return find[0];
        } else {
            final String placeURI = placeURI(this.id, ONT_MUSEUM);
            final String placeNameURI = placeNameURI(this.id, ONT_MUSEUM);

            Ont.getOntology().createIndividual(CIDOC.E53.getFullValue(), placeURI);
            Ont.getOntology().createIndividual(CIDOC.E44.getFullValue(), placeNameURI);

            Ont.getOntology().addLabel(placeNameURI, museum);

            Ont.getOntology().connectIndividuals(placeURI, CIDOC.P2.getFullValue(), CType.MUSEUM.getURI());
            Ont.getOntology().connectIndividuals(placeURI, CIDOC.P87.getFullValue(), placeNameURI);

            if (!StringUtil.isNullOrEmpty(cityURI)) {
                Ont.getOntology().connectIndividuals(placeURI, CIDOC.P89.getFullValue(), cityURI);
            }

            return placeURI;
        }
    }

    @Override
    public void toIndexDocument(final Document doc) {
        if (this.museum != null) {
            doc.add(SearchMD.MUSEUM.createField(this.museum));
            doc.add(SearchMD.CONTENT.createField(this.museum));

            if (this.city != null) {
                doc.add(SearchMD.CONTENT.createField(this.city));

                if (this.country != null) {
                    doc.add(SearchMD.CONTENT.createField(this.country));
                }
            }
        }
    }
}
